package com.orientation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.orientation.commom.exception.CustomException;
import com.orientation.dto.BatchVo;
import com.orientation.entity.Class;
import com.orientation.entity.*;
import com.orientation.mapper.ClassMapper;
import com.orientation.mapper.ReserveMapper;
import com.orientation.mapper.StudentMapper;
import com.orientation.service.ClassService;
import com.orientation.service.MajorService;
import com.orientation.service.ReserveService;
import com.orientation.service.StudentService;
import com.orientation.utils.BeanConvertUtils;
import com.orientation.utils.PageUtils;
import com.orientation.vo.ReserveVo;
import com.orientation.vo.StudentProgressVo;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * <p>
 * 报到 服务实现类
 * </p>
 *
 * @author xuandian
 * @since 2022-3-9
 */
@Service
public class ReserveServiceImpl extends ServiceImpl<ReserveMapper, Reserve> implements ReserveService {
    @Resource
    private ReserveMapper reserveMapper;
    @Resource
    private StudentMapper studentMapper;
    @Resource
    private StudentService studentService;
    @Resource
    private ReserveService reserveService;
    @Resource
    private MajorService majorService;
    @Resource
    private ClassMapper classMapper;

    @Resource
    private ClassService classService;


    // //完成度
    @Override
    public StudentProgressVo progress(String collegeId) {
        StudentProgressVo studentProgressVo = new StudentProgressVo();
        //总学生
        List<Student> students = studentService.list(Wrappers.<Student>lambdaQuery().eq(StringUtils.hasLength(collegeId), Student::getCollegeId, collegeId));
        if (!CollectionUtils.isEmpty(students)) {
            List<String> list = students.stream().map(Student::getStudentId).distinct().collect(Collectors.toList());
            //报道表存在学生信息
            // List<Reserve> reserveList = reserveMapper.selectList(new LambdaQueryWrapper<Reserve>().isNotNull(true, Reserve::getStudentId));
            List<Reserve> reserveList = reserveMapper.selectList(new LambdaQueryWrapper<Reserve>().in(!CollectionUtils.isEmpty(list), Reserve::getStudentId, list));

            // Map<Integer, List<Reserve>> listMap = reserveList.stream().collect(groupingBy(Reserve::getStatus));
//            if (!CollectionUtils.isEmpty(reserveList)) {
            //过滤已经报道的情况 filter 满足调价的数据
            List<Reserve> filterByStage = reserveList.stream().filter(reserve -> reserve.getStatus() == 3).collect(Collectors.toList());
            studentProgressVo.setNotNum(students.size() - filterByStage.size());
            studentProgressVo.setReserveNum(reserveList.size());
            studentProgressVo.setStudentNum(students.size());
            if (students.size() > 0) {
                BigDecimal installRate = new BigDecimal(filterByStage.size()).multiply(new BigDecimal("100")).divide(new BigDecimal(students.size()), 2, BigDecimal.ROUND_HALF_UP);
                studentProgressVo.setFinishProgress(installRate);
            }
        }
//        }
        return studentProgressVo;
    }

    @Override
    public void auditBatch(BatchVo batchVo) {
        List<Reserve> reserveList = reserveService.listByIds(batchVo.getIds());
        for (Reserve reserve : reserveList) {
            reserve.setRealTime(LocalDateTime.now());
            if (reserve.getStatus().equals(Integer.valueOf(batchVo.getReserveType()))) {
                throw new CustomException("18", "存在需要修改阶段和当前阶段一致");
            }
            reserve.setStatus(Integer.valueOf(batchVo.getReserveType()));
        }
        updateBatchById(reserveList);

    }

    @Override
    public Page<ReserveVo> queryReserveVo(Integer pageNum, Integer pageSize, String studentName, String majorId, String status, String studentId, String classId, String startTime, String endTime, String adviserId) {
        List<ReserveVo> reserveVoList = getReserveVos(studentName, majorId, status, studentId, classId, startTime, endTime, adviserId);
        return PageUtils.getPage(reserveVoList, pageNum, pageSize);
    }


    private List<ReserveVo> getReserveVos(String studentName, String majorId, String status, String studentId, String classId, String startTime, String endTime, String adviserId) {
        List<ReserveVo> reserveVoList = new ArrayList<>();

        List<Major> majors = majorService.list(Wrappers.<Major>lambdaQuery().eq(StringUtils.hasLength(majorId), Major::getSid, majorId).eq(Major::getAdviserId, adviserId));
        List<String> majorIds = majors.stream().map(Major::getSid).collect(Collectors.toList());
        List<Student> students = studentService.list(Wrappers.<Student>lambdaQuery().in(!CollectionUtils.isEmpty(majorIds), Student::getMajorId, majorIds)
                .eq(StringUtils.hasLength(classId), Student::getClassId, classId).isNotNull(true, Student::getClassId)
                .like(StringUtils.hasText(studentName), Student::getStudentName, studentName));
        List<String> classIds = students.stream().map(Student::getClassId).distinct().collect(Collectors.toList());
        List<Class> classes = classService.list(Wrappers.<Class>lambdaQuery().in(!CollectionUtils.isEmpty(classIds), Class::getSid, classIds));
        if (!CollectionUtils.isEmpty(students)) {
            //根据身份证去重
            List<Student> distinct = students.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getIdCardNo))), ArrayList::new));
            //过滤学号为空 的字段
            List<Student> studentList = distinct.stream().filter((Student student) -> !org.apache.commons.lang3.StringUtils.isEmpty(student.getStudentId())).collect(Collectors.toList());
            //得到studentIds
            List<String> studentIds = studentList.stream().map(Student::getStudentId).collect(Collectors.toList());
            LambdaQueryWrapper<Reserve> reserveWrapper = new LambdaQueryWrapper<>();
            if (!CollectionUtils.isEmpty(studentIds)) {
                reserveWrapper.in(Reserve::getStudentId, studentIds);
            }
            if (StringUtils.hasLength(status)) {
                reserveWrapper.in(Reserve::getStatus, status);
            }
            if (StringUtils.hasLength(studentId)) {
                reserveWrapper.in(Reserve::getStudentId, studentId);
            }
            if (StringUtils.hasLength(startTime)) {
                reserveWrapper.ge(Reserve::getRealTime, startTime);
            }
            if (StringUtils.hasLength(endTime)) {
                reserveWrapper.le(Reserve::getRealTime, endTime);
            }
            // if (org.apache.commons.lang3.StringUtils.isNotEmpty(pileQueryDto.getStartTime())) {
            //     query.ge(PileInfo::getEndDate, pileQueryDto.getStartTime());
            // }
            // if (org.apache.com
            // mons.lang3.StringUtils.isNotEmpty(pileQueryDto.getEndTime())) {
            //     query.le(PileInfo::getEndDate, pileQueryDto.getEndTime());
            // }
            List<Reserve> reservations = reserveMapper.selectList(reserveWrapper);
            reserveVoList = BeanConvertUtils.copyListProperties(reservations, ReserveVo::new);

            List<Student> studentLists = studentList.stream().filter(r -> reservations.stream().map(Reserve::getStudentId).collect(toList()).contains(r.getStudentId())).collect(toList());
            //
            for (ReserveVo reserveVo : reserveVoList) {
                for (Student student : studentLists) {
                    if (student.getStudentId().equals(reserveVo.getStudentId())) {
                        reserveVo.setStudentName(student.getStudentName());
                        reserveVo.setCollegeId(student.getCollegeId());
                        reserveVo.setMajorId(student.getMajorId());
                        reserveVo.setClassId(student.getClassId());
                    }

                }

            }
            for (ReserveVo vo : reserveVoList) {
                for (Class clazz : classes) {
                    if (vo.getClassId().equals(clazz.getSid())) {
                        vo.setClassName(clazz.getClassName());
                    }
                }
                for (Major major : majors) {
                    if (vo.getMajorId().equals(major.getSid())) {
                        vo.setMajorName(major.getMajorName());
                    }
                }
            }
            // for (ReserveVo reserveVo : reserveVos) {
            //     if (StringUtils.hasLength(reserveVo.getStudentName()) && StringUtils.hasLength(reserveVo.getMajorName())) {
            //         reserveVoList.add(reserveVo);
            //     } else {
            //         throw new CustomException("18", "当前条件下无数据信息");
            //     }
            // }
        }
        reserveVoList = reserveVoList.stream().sorted(Comparator.comparingInt(ReserveVo::getStatus).thenComparing(ReserveVo::getClassName)).collect(Collectors.toList());
        return reserveVoList;
    }

    @Override
    public void insertSave(Reserve reserve) {
        if (!ObjectUtils.isEmpty(reserve) && StringUtils.hasLength(reserve.getStudentId()) && reserve.getReserveTime() != null) {
            if (reserve.getAddress() == null) {
                throw new CustomException("18", "必要信息填写错误");
            }
            Reserve one = this.getOne(Wrappers.<Reserve>lambdaQuery().eq(Reserve::getStudentId, reserve.getStudentId()));
            if (!ObjectUtils.isEmpty(one)) {

                if (one.getStatus().equals(3)) {
                    throw new CustomException("18", "你已经报道，请不要重复用预约");
                }
                reserve.setSid(one.getSid());
//                throw new CustomException("18", "你已经预约过，请不要重复用预约");
            }

            reserve.setStatus(1);
            this.saveOrUpdate(reserve);
        }
    }

    @Override
    public List<ReserveVo> getReserveVosAll(String id, String status, String studentId, String realTime) {
        List<ReserveVo> reserveVos = new ArrayList<>();
        List<Student> students = studentService.list(Wrappers.<Student>lambdaQuery().eq(StringUtils.hasLength(id), Student::getCollegeId, id)
                .or().eq(StringUtils.hasLength(id), Student::getMajorId, id).or().eq(StringUtils.hasLength(id), Student::getClassId, id)
                .eq(StringUtils.hasLength(studentId), Student::getStudentId, studentId)
                .isNotNull(true,Student::getClassId));
        List<String> classIds = students.stream().map(Student::getClassId).distinct().collect(Collectors.toList());
        List<Class> classes = classService.list(Wrappers.<Class>lambdaQuery().in(!CollectionUtils.isEmpty(classIds), Class::getSid, classIds));
        if (!CollectionUtils.isEmpty(students)) {
            //根据身份证去重
            // List<Student> distinct = students.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Student::getIdCardNo))), ArrayList::new));
            //过滤学号为空 的字段
            List<Student> studentList = students.stream().filter((Student student) -> !org.apache.commons.lang3.StringUtils.isEmpty(student.getStudentId())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(studentList)) {
                throw new CustomException("18", "暂无学生信息");
            }
            //得到studentIds
            List<String> studentIds = studentList.stream().map(Student::getStudentId).collect(Collectors.toList());
            List<String> majorIds = studentList.stream().map(Student::getMajorId).distinct().collect(Collectors.toList());
            List<Major> majors = majorService.list(Wrappers.<Major>lambdaQuery().in(!CollectionUtils.isEmpty(majorIds), Major::getSid, majorIds));
            LambdaQueryWrapper<Reserve> reserveWrapper = new LambdaQueryWrapper<>();
            if (!CollectionUtils.isEmpty(studentIds)) {
                reserveWrapper.in(Reserve::getStudentId, studentIds);
            }
            if (StringUtils.hasLength(status)) {
                reserveWrapper.in(Reserve::getStatus, status);
            }
            if (StringUtils.hasLength(realTime)) {
                reserveWrapper.like(Reserve::getRealTime, realTime);
            }
            List<Reserve> reservations = reserveMapper.selectList(reserveWrapper);
            reserveVos = BeanConvertUtils.copyListProperties(reservations, ReserveVo::new);
            List<Student> studentLists = studentList.stream().filter(r -> reservations.stream().map(Reserve::getStudentId).collect(toList()).contains(r.getStudentId())).collect(toList());
            //
            for (ReserveVo reserveVo : reserveVos) {
                for (Student student : studentLists) {
                    if (student.getStudentId().equals(reserveVo.getStudentId())) {
                        reserveVo.setStudentName(student.getStudentName());
                        reserveVo.setCollegeId(student.getCollegeId());
                        reserveVo.setMajorId(student.getMajorId());
                        reserveVo.setClassId(student.getClassId());
                    }

                }
            }
            for (ReserveVo vo : reserveVos) {
                for (Class clazz : classes) {
                    if (vo.getClassId().equals(clazz.getSid())) {
                        vo.setClassName(clazz.getClassName());
                    }
                }
                for (Major major : majors) {
                    if (vo.getMajorId().equals(major.getSid())) {
                        vo.setMajorName(major.getMajorName());
                    }
                }
            }

        }
        reserveVos = reserveVos.stream().sorted(Comparator.comparingInt(ReserveVo::getStatus).thenComparing(ReserveVo::getClassName)).collect(Collectors.toList());
        return reserveVos;
    }

    @Override
    public IPage<ReserveVo> queryReserveVoAll(Integer pageNum, Integer pageSize, String id, String status, String studentId, String realTime) {
        List<ReserveVo> reserveVoList = getReserveVosAll(id, status, studentId, realTime);
        return PageUtils.getPage(reserveVoList, pageNum, pageSize);
    }


}
